package com.archermind.sessionpool;

import java.util.LinkedList;

import java.util.List;

import com.archermind.boc.Logger;
import com.archermind.boc.dal.business.service.BizService;
import com.archermind.boc.dal.business.service.UserService;
import com.archermind.boc.dal.business.support.DispatchSupport;
import com.archermind.boc.domain.Biz;
import com.archermind.boc.domain.BizStatus;
import com.archermind.boc.domain.IQ;
import com.archermind.boc.domain.User;
import com.archermind.boc.ehcache.UserCache;
import com.archermind.boc.ehcache.UserEhcacheImpl;
import com.archermind.boc.socket.out.IBocSocketWriter;
import com.archermind.boc.xml.ApplicationContextFactory;

public class BizSessionPool {
	private static Logger log = Logger.getLogger(BizSessionPool.class.getName());
	private static List<BizSession> bizs = new LinkedList<BizSession>();
	private static final String SESSION_POOL = "[session pool]";

	public synchronized static List<BizSession> getBizs() {

		return bizs;
	}

	public synchronized static void addBiz(BizSession biz) {
		biz.setCreateTime(System.currentTimeMillis());
		bizs.add(biz);
		log.info(SESSION_POOL + " add new bizSession, biz id: " + biz.getBizid());
	}

	public synchronized static BizSession getFirstBiz() {
		return bizs.get(0);
	}

	public synchronized static void removeBiz(int bizid) {
		for (BizSession bizSession : bizs) {
			if (bizSession.getBizid() == bizid) {
				log.info(SESSION_POOL + " remove  bizSession, biz id: " + bizSession.getBizid());
				bizs.remove(bizSession);
				return;
			}
		}

	}

	public synchronized static BizSession getbiz(int bizid) {
		for (BizSession bizSession : bizs) {
			if (bizSession.getBizid() == bizid) {
				return bizSession;
			}
		}
		return null;
	}

	public   static void protectBizs() {
		log.info("[pull pool] start check ");
		
		if (bizs != null && bizs.size() > 0) {
			for (int i = 0; i < bizs.size(); i++) {
				BizSession biz = bizs.get(i);
				log.info("[pull pool] check bizsession,id: "+biz.getBizid());
				long currentTime = System.currentTimeMillis();
				long betweenTime = currentTime - biz.getCreateTime();
				
				if (betweenTime > biz.getBizTimeOutSecond() * 1000) {
					log.info(SESSION_POOL + " bizSession timeout, biz id: " + biz.getBizid());
					bizs.remove(i);
					i--;
					modifyBizStatus(biz.getBizid(), BizStatus.BIZSTATUS_TIMEOUT);
					removeBizFromUsercache(biz.getBizid());
					sendBackToDevice(biz.getBizid());
					
					
					
					// minusSessionNum(biz);
				}
			}
		}
	}

	/**
	 * 授权完成，包括 同意/拒绝/拒绝 情况
	 */
	public static void grantDone(int id, String status) {
		log.info(SESSION_POOL + " bizSession " + status + ", biz id: " + id);
		modifyBizStatus(id, status);
		removeBizFromUsercache(id);
		removeBiz(id);
	}

	/**
	 * 修改biz持久状态
	 * 
	 * @param id
	 */
	public static void modifyBizStatus(int id, String status) {
		BizService service = new BizService();
		Biz biz = service.getBizById(id);
		biz.setStatus(status);
		String logs = biz.getLog();
		biz.setLog(logs + "流水号： " + biz.getBizid() + status);
		if (!service.modifyBiz(biz)) {
			log.error("biz update is fail");
		}
	}

	/**
	 * 释放usercache里的biz，busy字段设成leisure
	 * 
	 * @param bizid
	 */
	public static void removeBizFromUsercache(int bizid) {
		UserEhcacheImpl ehcacheImpl = new UserEhcacheImpl();
		List<UserCache> ls = ehcacheImpl.getUserCacheByBizid(bizid);
		ehcacheImpl.releaseBiz(ls);
	}

	/**
	 * 分别返回xml给授权和经办
	 * 
	 * @param id
	 */
	public static void sendBackToDevice(int id) {
		BizService service = new BizService();
		Biz biz = service.getBizById(id);
		int grantId = biz.getToBankNum();
		int operatorId = biz.getFromBankNum();

		UserService userService = new UserService();
		User grant = userService.getUserById(grantId);
		User operator = userService.getUserById(operatorId);

		UserEhcacheImpl ehcache = new UserEhcacheImpl();
		IBocSocketWriter bw = (IBocSocketWriter)ApplicationContextFactory.getContext().getBean("bocSocketWriter");

		if (grant != null) {

			String grantSessionId = ehcache.getUserCacheById(grantId).getSessionID();
			IQ gm = DispatchSupport.setSessionOutMessage(grant, operator, grantSessionId, biz);
			bw.write(gm);
		}

		if (operator != null) {

			String operatorSessionId = ehcache.getUserCacheById(operatorId).getSessionID();
			IQ om = DispatchSupport.setSessionOutMessage(grant, operator, operatorSessionId, biz);
			bw.write(om);
		}

	}

	/*
	 * 计数用 暂时不用
	 */
	// public static void minusSessionNum(BizSession biz) {
	// UserCache uc = biz.getUserCache();
	// if (uc != null) {
	// Cache cache = EhcacheUtil.getCache();
	// net.sf.ehcache.Element e = cache.get(uc.getUserid());
	// UserCache cache4user = (UserCache) e.getObjectValue();
	// cache4user.setSessionNum(cache4user.getSessionNum() - 1);
	// if (cache4user.getSessionNum() == 0) {
	// cache4user.setIsBusy(UserStatus.USER_LEISURE);
	// }
	// }
	// }
}
